package actions;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.GanttRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * 用jfreechart生成图片
 * @author taotao
 */
public class CommonDisplayChartAction extends Action {

    /**
     * @param mapping action mapping
     * @param form action form
     * @param request http request
     * @param response http response
     * @return action forward
     * @throws Exception any exception
     */
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        response.setBufferSize(100 * 1024);// 100KB
        // 显示指定类型的jfreechart
        buildMyChart(request, response);
        return null;
    }

    /**
     * 根据请求的参数，构造指定的图表.
     * @param request http
     * @param response http
     * @throws Exception e
     */
    private void buildMyChart(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String type = request.getParameter("type");
        if ("pie3d".equals(type)) {
            creatPieImgFile(request, response);
        } else if ("line".equals(type)) {
            creatLineImgFile(request, response);
        } else if ("bar3d".equals(type)) {
            creatBarImgFile(request, response);
        } else if ("gantt".equals(type)) {
            creatGantteImgFile(request, response);
        } else if ("xystep".equals(type)) {
            creatXYStepImgFile(request, response);
        } else if ("area".equals(type)) {
            creatAreaImgFile(request, response);
        }
    }

    /**
     * 生成柱状图图表
     * @param request http request
     * @param response http response
     * @throws Exception e
     */
    private void creatBarImgFile(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // 从request中获取所需参数
        request.getAttribute("dataParamxxx");
        double[][] data = new double[][] { { 672, 766, 223, 540, 126 },
                { 325, 521, 210, 340, 106 }, { 332, 256, 523, 240, 526 } };
        String[] rowKeys = { "苹果", "梨子", "葡萄" };
        String[] columnKeys = { "北京", "上海", "广州", "成都", "深圳" };
        CategoryDataset pDCD = DatasetUtilities.createCategoryDataset(rowKeys,
                columnKeys, data);
        JFreeChart pJFC = ChartFactory.createBarChart("水果产量", "水果", "产量", pDCD,
                PlotOrientation.VERTICAL, true, true, false);
        pJFC.getLegend().setBorder(BlockBorder.NONE);
        pJFC.setBackgroundPaint(Color.white);// 可选，设置图片背景色
        pJFC.setBorderVisible(true);
        pJFC.setBorderPaint(Color.cyan);
        pJFC.setBorderStroke(new BasicStroke(0));
        CategoryPlot plot = (CategoryPlot) pJFC.getPlot();
        BarRenderer render = (BarRenderer) plot.getRenderer();
        render.setMaximumBarWidth(0.2);
        // 每个柱的边框颜色
        render.setOutlinePaint(Color.white);
        // 显示每个柱的数值，并修改该数值的字体属性
        render.setItemLabelAnchorOffset(1.0);
        render.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        render.setItemLabelFont(new Font("黑体", Font.PLAIN, 12));
        render.setItemLabelsVisible(true);
        /*------设置柱状体与图片边框的上下间距---*/
        ValueAxis rAxis = plot.getRangeAxis();
        rAxis.setUpperMargin(0.1);
        rAxis.setLowerMargin(0.1);
        /*---------设置每一组柱状体之间的间隔---------*/
        render.setItemMargin(0.3);
        // ChartUtilities.saveChartAsJPEG(jpg, pJFC, 400, 300);
        ChartUtilities.writeChartAsPNG(response.getOutputStream(), pJFC, 400,
                300);
        // Write the image map to the PrintWriter
        // ByteArrayOutputStream mapInfo = new ByteArrayOutputStream();
        // ChartUtilities.writeImageMap(new PrintWriter(mapInfo, true),
        // "test-map", info, false);
        // request.getSession().setAttribute("picmap01",
        // mapInfo.toString("UTF-8"));

    }

    private XYSeriesCollection createXYDataSet() {
        XYSeries xyseries = new XYSeries("data");
        xyseries.add(1, 1);
        xyseries.add(10, 2);
        xyseries.add(11, 3);
        xyseries.add(12, 5);
        xyseries.add(13, 3);
        xyseries.add(14, 7);
        xyseries.add(15, 5);
        xyseries.add(16, 0);
        xyseries.add(17, 23);
        xyseries.add(18, 25);
        xyseries.add(19, 33);
        xyseries.add(20, 22);
        return new XYSeriesCollection(xyseries);

    }

    /**
     * 生成区域图图表.
     * @param request http request
     * @param response http response
     * @throws Exception e
     */
    private void creatAreaImgFile(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        request.getAttribute("dataParamxxx");
        // 三组数据
        final double[][] data = new double[][] {
                { 9.0, 8.2, 7.5, 8.3, 8.8, 9.8, 7.8, 8.9, 6.7, 11.9, 6.8, 10.8 },
                { 5.9, 13.2, 7.9, 5.5, 13.1, 9.0, 4.9, 7.9, 8.8, 7.4, 3.9, 13.9 },
                { 8.0, 11.2, 9.8, 12.0, 7.0, 4.9, 11.9, 6.5, 13.2, 7.9, 5.5,
                        13.1 } };
        String[] city = { "北京", "上海", "广州" };
        String[] month = { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月",
                "九月", "十月", "十一月", "十二月" };
        CategoryDataset dataset = DatasetUtilities.createCategoryDataset(city,
                month, data);
        JFreeChart chart = ChartFactory.createAreaChart("经济增长区域图", "月份", "增长率",
                dataset, PlotOrientation.VERTICAL, true, true, false);
        chart.setBackgroundPaint(Color.white);
        chart.setBorderVisible(true);
        chart.setBorderPaint(Color.cyan);
        chart.setBorderStroke(new BasicStroke(0));
        chart.getLegend().setBorder(BlockBorder.NONE);
        CategoryPlot plot = chart.getCategoryPlot();
        plot.setForegroundAlpha(0.5f);

        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
        domainAxis.setLowerMargin(0.0);
        domainAxis.setUpperMargin(0.0);

        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setLabelAngle(0 * Math.PI / 2.0);

        ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart, 400,
                300);

    }

    private void creatXYStepImgFile(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // 从request中获取所需参数
        request.getAttribute("dataParamxxx");

        JFreeChart pJFC = ChartFactory.createXYStepChart("XYStepChart",
                "Categary", "Value", createXYDataSet(),
                PlotOrientation.VERTICAL, true, true, false);

        XYPlot plot = pJFC.getXYPlot();

        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinesVisible(true);
        pJFC.setBackgroundPaint(Color.white);// 可选，设置图片背景色
        pJFC.setBorderPaint(Color.cyan);
        pJFC.setBorderStroke(new BasicStroke(0));
        pJFC.setBorderVisible(true);
        pJFC.getLegend().setBorder(BlockBorder.NONE);
        // 设置详细格式
        plot.setBackgroundPaint(Color.white);
        plot.getDomainAxis().setLabelFont(
                new Font("黑体", Font.TRUETYPE_FONT, 12));
        // 指定 section 轮廓线的颜色
        plot.setOutlinePaint(Color.white);
        ChartUtilities.writeChartAsPNG(response.getOutputStream(), pJFC, 400,
                300);
    }

    /**
     * 生成饼图图表.
     * @param request http request
     * @param response http response
     * @throws Exception e
     */
    private void creatPieImgFile(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // 从request中获取所需参数
        request.getAttribute("dataParamxxx");
        DefaultPieDataset pDPD = new DefaultPieDataset();
        pDPD.setValue("苹果", 100);
        pDPD.setValue("梨子", 200);
        pDPD.setValue("葡萄", 300);
        pDPD.setValue("香蕉", 300);
        pDPD.setValue("李子", 1);
        JFreeChart pJFC = ChartFactory.createPieChart("水果产量", pDPD, true, true,
                false);
        pJFC.setBackgroundPaint(Color.white);// 可选，设置图片背景色
        pJFC.setBorderPaint(Color.cyan);
        pJFC.setBorderStroke(new BasicStroke(0));
        pJFC.setBorderVisible(true);
        pJFC.getLegend().setBorder(BlockBorder.NONE);
        // 设置详细格式
        PiePlot plot = (PiePlot) pJFC.getPlot();
        plot.setBackgroundPaint(Color.white);
        plot.setLabelFont(new Font("黑体", Font.TRUETYPE_FONT, 12));
        plot.setLabelOutlinePaint(Color.white);
        // 指定 section 轮廓线的颜色
        plot.setOutlinePaint(Color.white);
        // 指定 section 的色彩
        plot.setSectionOutlinePaint(Color.white);
        plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{2}",
                new DecimalFormat("0.00%"), new DecimalFormat("0.00%")));
        plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator(
                "{0}: ({1}吨, {2})", new DecimalFormat("0.00%"),
                new DecimalFormat("0.00%")));
        ChartUtilities.writeChartAsPNG(response.getOutputStream(), pJFC, 400,
                300);
    }

    /**
     * 生成甘特图表.
     * @param request http request
     * @param response http response
     * @throws Exception e
     */
    private void creatGantteImgFile(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // 从request中获取所需参数
        request.getAttribute("dataParamxxx");
        SimpleDateFormat dfmat = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
        // 任务计划情况
        final TaskSeries s1 = new TaskSeries("Scheduled");
        s1.add(new Task("完成用户管理", dfmat.parse("2005-5-1"), dfmat
                .parse("2005-5-3")));
        s1.add(new Task("完成系统设置", dfmat.parse("2005-5-3"), dfmat
                .parse("2005-5-5")));
        s1.add(new Task("修改缺陷03", dfmat.parse("2005-5-6"), dfmat
                .parse("2005-5-8")));
        // 实际执行情况
        final TaskSeries s2 = new TaskSeries("Actual");
        s2.add(new Task("完成用户管理", dfmat.parse("2005-5-1"), dfmat
                .parse("2005-5-2")));
        s2.add(new Task("完成系统设置", dfmat.parse("2005-5-2"), dfmat
                .parse("2005-5-6")));
        s2.add(new Task("修改缺陷03", dfmat.parse("2005-5-7"), dfmat
                .parse("2005-5-9")));
        final TaskSeriesCollection collection = new TaskSeriesCollection();
        collection.add(s1);
        collection.add(s2);
        final JFreeChart pJFC = ChartFactory.createGanttChart("甘特图", // chart
                // title
                "任务", // domain axis label
                "日期", // range axis label
                collection, // data
                true, // include legend
                true, // tooltips
                false // urls
                );
        pJFC.setBackgroundPaint(Color.white);
        pJFC.setBorderVisible(true);
        pJFC.setBorderPaint(Color.cyan);
        pJFC.setBorderStroke(new BasicStroke(0));
        pJFC.getLegend().setBorder(BlockBorder.NONE);
        ((CategoryPlot) pJFC.getPlot()).getDomainAxis().setVisible(false);
        DateAxis axis = (DateAxis) ((CategoryPlot) pJFC.getPlot())
                .getRangeAxis();
        // 设置日期轴的日期格式.
        SimpleDateFormat format = new SimpleDateFormat("MM/dd", Locale.UK);
        axis.setDateFormatOverride(format);
        // 设置日期轴的单位.
        axis.setAutoTickUnitSelection(false);
        axis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, 1));// x轴单位间隔为1天
        GanttRenderer render = (GanttRenderer) ((CategoryPlot) pJFC.getPlot())
                .getRenderer();
        render.setMaximumBarWidth(0.04);
        render.setItemMargin(0.01);
        render.setItemLabelGenerator(new StandardCategoryItemLabelGenerator(
                "{1}", new SimpleDateFormat()));
        render.setItemLabelFont(new Font("宋体", Font.PLAIN, 9));
        render.setItemLabelAnchorOffset(-1.0);
        render.setItemLabelsVisible(true);

        ChartUtilities.writeChartAsPNG(response.getOutputStream(), pJFC, 400,
                300);
    }

    /**
     * 生成折线图图表.
     * @param request http request
     * @param response http response
     * @throws Exception e
     */
    private void creatLineImgFile(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // 从request中获取所需参数
        request.getAttribute("dataParamxxx");
        JFreeChart pJFC = ChartFactory.createXYLineChart("水果产量图", "月份", "产量",
                createXYDataSet(), PlotOrientation.VERTICAL, true, true, false);
        XYPlot plot = pJFC.getXYPlot();
        plot.getDomainAxis().setAutoRange(false);
        pJFC.setBackgroundPaint(Color.white);
        pJFC.setBorderVisible(true);
        pJFC.setBorderPaint(Color.cyan);
        pJFC.setBorderStroke(new BasicStroke(0));
        pJFC.getLegend().setBorder(BlockBorder.NONE);
        ChartUtilities.writeChartAsPNG(response.getOutputStream(), pJFC, 400,
                300);
    }
}